package com.bao.auth.server.biz.service.auth.impl;

import com.bao.auth.dto.auth.RoleAuthoritySaveDTO;
import com.bao.auth.dto.auth.UserRoleSaveDTO;
import com.bao.auth.entity.auth.RoleAuthority;
import com.bao.auth.entity.auth.User;
import com.bao.auth.entity.auth.UserRole;
import com.bao.auth.enumeration.auth.AuthorizeType;
import com.bao.auth.server.biz.dao.auth.RoleAuthorityMapper;
import com.bao.auth.server.biz.service.auth.ResourceService;
import com.bao.auth.server.biz.service.auth.RoleAuthorityService;
import com.bao.auth.server.biz.service.auth.UserRoleService;
import com.bao.common.constant.CacheKey;
import com.bao.core.utils.NumberHelper;
import com.bao.databases.mybatis.conditions.Wraps;
import com.bao.databases.mybatis.conditions.query.LbqWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import net.oschina.j2cache.CacheChannel;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class RoleAuthorityServiceImpl extends ServiceImpl<RoleAuthorityMapper, RoleAuthority> implements RoleAuthorityService {
  
    @Autowired
    private UserRoleService userRoleService;
    
    @Autowired
    private ResourceService resourceService;
    
    @Autowired
    private CacheChannel cache;
    
    @Override
    public boolean saveUserRole(UserRoleSaveDTO userRole) {
        //清空原本的角色绑定信息
        userRoleService.remove(Wraps.<UserRole>lbQ().eq(UserRole::getRoleId, userRole.getRoleId()));

        //构建新的角色绑定信息
        List<UserRole> list = userRole.getUserIdList().stream()
                .map((userId) -> UserRole.builder()
                        .userId(userId)
                        .roleId(userRole.getRoleId())
                        .build()
                ).collect(Collectors.toList());
        //报存
        userRoleService.saveBatch(list);
        
        //清除 用户所拥有的资源列表 缓存
        for (Long userId : userRole.getUserIdList()) {
            String key = CacheKey.buildKey(userId);
            cache.evict(CacheKey.USER_RESOURCE, key);
        }

        return true;
    }

    @Override
    public boolean saveRoleAuthority(RoleAuthoritySaveDTO dto) {
        //删除角色和资源的关联
        super.remove(Wraps.<RoleAuthority>lbQ().eq(RoleAuthority::getRoleId, dto.getRoleId()));
        
        List<RoleAuthority> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(dto.getResourceIdList())) {
            List<Long> menuIdList = resourceService.findMenuIdByResourceId(dto.getResourceIdList());
            if (CollectionUtils.isEmpty(dto.getMenuIdList())){
                dto.setMenuIdList(menuIdList);
            }else {
                dto.getMenuIdList().addAll(menuIdList);
            }
            //保存授予的资源
            List<RoleAuthority> resourceIdList = new HashSet<>(dto.getResourceIdList()).stream().map((menuId) -> RoleAuthority.builder()
                    .authorityType(AuthorizeType.MENU)
                    .authorityId(menuId)
                    .roleId(dto.getRoleId())
                    .build()
            ).collect(Collectors.toList());
            list.addAll(resourceIdList);
        }
        if(CollectionUtils.isNotEmpty(dto.getMenuIdList())) {
            //保存授予的资源
            List<RoleAuthority> menuList = new HashSet<>(dto.getMenuIdList()).stream().map((menuId) -> RoleAuthority.builder()
                    .authorityType(AuthorizeType.MENU)
                    .authorityId(menuId)
                    .roleId(dto.getRoleId())
                    .build()
            ).collect(Collectors.toList());
            list.addAll(menuList);
        }
        saveBatch(list);

        //清理缓存
        LbqWrapper<UserRole> wrapper = Wraps.<UserRole>lbQ().select(UserRole::getUserId).eq(UserRole::getRoleId, dto.getRoleId());
        List<Long> useridList = userRoleService.listObjs(wrapper, (userId) -> NumberHelper.longValueOf0(userId));
        if (CollectionUtils.isNotEmpty(useridList)) {
            useridList.forEach(userId -> {
                log.info("清理了 {} 的菜单/资源",userId);
                cache.evict(CacheKey.USER_RESOURCE, String.valueOf(userId));
            });
        }
        return true;
    }
}
